<?php
/**
 * CK 开发框架
 * User: Clake
 * Date: 15/6/26
 * Time: 01:54
 */

namespace CK\Util;


use CK\Core\Component;
use CK\Ex\ExNotFound;

/**
 * 操作 Cookie 类
 * Class Cookie
 *
 * @package CK\Util
 */
class Cookie extends Component {
    private static $_instance = [];

    private $_conf = [
        //Cookie 前缀
        'prefix'=>'ck_',
        //Cookie 作用路径
        'path'=>null,
        //Cookie 作用域
        'domain'=>null,
        //Cookie 过期时间
        'expire'=>null,
        //加密KEY
        'cipher'=>null
    ];

    private $_prefix;
    private $_path;
    private $_domain;
    private $_expire;
    private $_cipher;

    /**
     * @param null $conf
     *
     * @return self
     */
    public static function inst($conf=null) {
        $class = md5(json_encode($conf));
        if (!isset(self::$_instance[$class])) {
            self::$_instance[$class] = new self($conf);
        }
        return self::$_instance[$class];
    }

    public function __construct($conf=null) {
        if (empty($conf)) {
            $conf = C('cookie');
        }
        if (!empty($conf)) {
            $this->_conf = Arr::mrg($this->_conf,$conf);
        }
        $this->_prefix = $this->_conf['prefix'];
        $this->_path   = $this->_conf['path'];
        $this->_domain = $this->_conf['domain'];
        $this->_expire = $this->_conf['expire'];
        $this->_cipher = $this->_conf['cipher'];
    }

    /**
     * 设置一个 Cookie 到浏览器
     *
     * @param $key
     * @param $value
     *
     * @return bool
     */
    public function set($key,$value,$expire=null,$path=null,$domain=null) {
        if (!empty($this->_cipher)) {
            $value = Cipher::inst($this->_cipher)->encrypt($value);
        }

        if ($expire === null) {
            $expire = $this->_expire;
        }

        if ($path === null) {
            $path = $this->_path;
        }

        if ($domain === null) {
            $domain = $this->_domain;
        }

        $cookie_name = $this->_prefix.$key;
        return setcookie($cookie_name,$value,$expire,$path,$domain);
    }

    /**
     * 新版设置 >= php 7.3
     * @param $key
     * @param $value
     * @param $options
     *
     * @return bool
     */
    public function setV2($key,$value,$options) {
        if (!empty($this->_cipher)) {
            $value = Cipher::inst($this->_cipher)->encrypt($value);
        }

        $cookie_name = $this->_prefix.$key;
        return setcookie($cookie_name,$value,$options);
    }

    /**
     * 得到一个 Cookie 值
     * @param $key
     *
     * @return null|string
     */
    public function get($key) {
        $cookie_name = $this->_prefix.$key;
        $value = isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] : null;
        if (!empty($value) && !empty($this->_cipher)) {
            $value = Cipher::inst($this->_cipher)->decrypt($value);
        }
        return $value;
    }

    /**
     * 删除一个 Cookie
     *
     * @param $key
     *
     * @return bool
     */
    public function remove($key) {
        $cookie_name = $this->_prefix.$key;
        return setcookie($cookie_name,null,time()-300,$this->_path,$this->_domain);
    }

    /**
     * 得到COOKIE原始值
     * @param $key string
     *
     * @return mixed
     */
    public function getRaw($key) {
        $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : null;
        return $value;
    }

    /**
     * 设置读取COOKIE前缀
     * @param $prefix
     */
    public function setPrefix($prefix) {
        $this->_prefix = $prefix;
    }

    /**
     * 设置COOKIE读取路径
     * @param mixed $path
     */
    public function setPath($path) {
        $this->_path = $path;
    }

    /**
     * 设置COOKIE作用域
     * @param mixed $domain
     */
    public function setDomain($domain) {
        $this->_domain = $domain;
    }

    /**
     * 设置COOKIE过过期时间
     * @param mixed $expire
     */
    public function setExpire($expire) {
        $this->_expire = $expire;
    }

    /**
     * 设置COOKIE加密KEY
     * @param mixed $cipher
     */
    public function setCipher($cipher) {
        $this->_cipher = $cipher;
    }
}